1. Field of the Invention
The present invention relates generally to profiling schemes, and more specifically to profiling schemes having a low overhead.
2. Description of the Related Art
Profiling is a general term for techniques that allow software developers to collect data on various characteristics of running computer applications. The collected data can then be used to understand what parts of the application being profiled (also called “target application”) may be modified in order to improve the performance of the application. The term “CPU profiling” is used for those techniques that measure the time that an application spends in various parts of its code. These “parts” may be source code-level functions (subroutines, methods) of the application, basic blocks of code, individual source code lines, machine instructions, etc. A CPU profiling tool ultimately presents the user with the data (many formats are possible) showing which parts of the application code consumed what proportion of the total execution time.
In practice, and especially when working on large applications, developers often need to know not just in which parts of the code the application spent most of its time, but also something about why this happened. One category of data that often helps to answer that question, is the number of calls made to every function in the application. For example, the information that the application spent 50 percent of its execution time in function foo( ) is useful, but it is even more useful to know whether this time was spent in just a single call to foo( ), or in 1000 calls to foo( ). In the former case, the focus would be on how to improve foo( ) itself, whereas in the latter case, it also makes sense to think how to decrease the number of calls to foo( ). Additional data that can help in this situation is the knowledge of all contexts in which foo( ) was called. For example, it may be determined that foo( ) is called 10 times by function bar1( ), and 990 times by function bar2( ). If every call to foo( ) takes the same amount of time, it makes sense for the developer to look at the code of bar2( ), in order to decrease the number of calls to foo( ). Changing the number of calls to foo( ) from bar1( ) will not make a significant improvement and as such, does not require a developer to focus his efforts here.
Another example that illustrates the importance of recording of the number of calls to functions, is when the application contains a call that has far-reaching side effects. For example, just a single quick call to a special function that turns on/off security checks in many other functions, may dramatically affect the overall performance of the application. It is therefore important to know whether such calls have been made, and if so, how many calls have been made, even if they are relatively short. However, it turns out that recording both the exact number of calls and the exact timing information during profiling is quite computationally expensive under an instrumentation based profiling scheme.
In light of the foregoing, it is desirable to implement a scheme for an improved profiling technique that provides the benefits of instrumentation-based profiling (information about the exact number of calls) at an overhead that is much smaller than that for conventional instrumentation-based profiling.